import UglyMap from '@/utils/uglyMap'
import moment from 'moment'

HolmesImpl.prototype = {
  goodsList: null,
  setGoodsList: function (value) {
    if (!value) {
      return
    }
    const array = this.validateGoods(value)
    this.goodsList = this.convertToGoods(array)
    this.handleGoods()
  },
  getGoodsList: function () {
    return this.goodsList
  },
  supplierList: null,
  setSupplierList: function (value) {
    if (!value) {
      return
    }
    const array = this.validateSupplier(value)
    this.supplierList = this.convertToSupplier(array)
    this.handleSupplier()
  },
  getSupplierList: function () {
    return this.supplierList
  },
  purchaseOrderList: null,
  setPurchaseOrderList: function (value) {
    if (!value) {
      return
    }
    const array = this.validatePurchaseOrder(value)
    this.purchaseOrderList = this.convertToPurchaseOrder(array)
    this.handleOrderGoods(this.purchaseOrderList)
  },
  getPurchaseOrderList: function () {
    return this.purchaseOrderList
  },
  purchaseReceiveOrderList: null,
  setPurchaseReceiveOrderList: function (value) {
    if (!value) {
      return
    }
    const array = this.validatePurchaseReceiveOrder(value)
    this.purchaseReceiveOrderList = this.convertToPurchaseReceiveOrder(array)
    this.handleOrderGoods(this.purchaseReceiveOrderList)
  },
  getPurchaseReceiveOrderList: function () {
    return this.purchaseReceiveOrderList
  }
}

export default function HolmesImpl() {

  const concentrationNumberArray = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.', '+', '-', '(', ')', ' ']
  const specificationNumberArray = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '.']

  // / private methods

  const toArray = function (value) {
    let array
    if (value instanceof Array) {
      array = value
    } else if (value instanceof Object) {
      array = [value]
    } else {
      throw new Error('数据类型只支持数组和对象')
    }
    return array
  }

  const split = function (numberArray, value) {
    let str1 = value
    let str2 = ''
    for (let i = 0, len = value.length; i < len; i++) {
      if (!numberArray.includes(value[i])) {
        str1 = value.substring(0, i)
        str2 = value.substring(i)
        break
      }
    }
    return [str1, str2]
  }

  const splitGoodsBatchCode = function (value) {
    if (value) {
      let index1 = value.indexOf(',')
      if (index1 < 0) {
        index1 = value.indexOf('，')
      }
      if (index1 < 0) {
        return [value, '', '', '', '']
      }
      const index2 = value.lastIndexOf('-')
      if (index2 < 0) {
        const specificationArray = split(specificationNumberArray, value.substring(index1 + 1))
        return [value.substring(0, index1), '', '', specificationArray[0], specificationArray[1]]
      }
      const concentrationArray = split(concentrationNumberArray, value.substring(index1 + 1, index2))
      const specificationArray = split(specificationNumberArray, value.substring(index2 + 1))
      return [value.substring(0, index1), concentrationArray[0], concentrationArray[1], specificationArray[0], specificationArray[1]]
    }
    return ''
  }
  const getFieldValue = function (e, fieldArray) {
    for (const i in fieldArray) {
      if (e[fieldArray[i]]) {
        return e[fieldArray[i]]
      }
    }
    return null
  }

  // / public methods
  this.fieldNames = {
    orderCode: '单据编号',
    createDate: '日期',
    warehouseName: ['发货仓库', '收货仓库', '仓库'],
    supplierFullCode: '代码',
    supplierCode: ['供应商编号', '助记码'],
    supplierName: ['供应商名称', '供应商', '名称'],
    principal: '联系人',
    tel: '电话',
    bank: '开户银行',
    account: '银行账号',
    expectArriveDate: '交货日期',
    customerCode: '客户编码',
    customerName: '购货单位',
    goodsFullCode: ['产品长代码', '代码', '物料长代码'],
    goodsCode: '规格型号',
    goodsAbbr: '助记码',
    goodsName: ['产品名称', '名称', '物料名称'],
    goodsAlias: '别名',
    goodsCategory: ['全名', '产品类型'],
    unit: ['销售计量单位', '单位'],
    goodsBatchCode: '批号',
    expirationDate: '有效期至',
    quantity: ['实发数量', '实收数量', '数量'],
    receiveAddress: '收件地址',
    province: '省份',
    city: '城市',
    bizer: '业务员',
    eidtor: '制单员',
    memo: '摘要',
    originalGoodsCode: '别名',
    originalGoodsBatchCode: '原始批号',

  }
  this.validateGoods = function (value) {
    const array = toArray(value)
    const filedNames = this.fieldNames
    let fieldValue
    array.forEach(e => {
      fieldValue = getFieldValue(e, filedNames.goodsFullCode)
      if (!fieldValue) {
        throw new Error('数据格式错误：缺少字段【' + fieldValue + '】')
      }
      if (!e[filedNames.goodsCode]) {
        throw new Error('数据格式错误：缺少字段【' + filedNames.goodsCode + '】')
      }
      if (!e[filedNames.goodsAbbr]) {
        throw new Error('数据格式错误：缺少字段【' + filedNames.goodsAbbr + '】')
      }
      fieldValue = getFieldValue(e, filedNames.goodsName)
      if (!fieldValue) {
        throw new Error('数据格式错误：缺少字段【' + fieldValue + '】')
      }
      fieldValue = getFieldValue(e, filedNames.unit)
      if (!fieldValue) {
        throw new Error('数据格式错误：缺少字段【' + fieldValue + '】')
      }
    })
    return array
  }
  this.convertToGoods = function (array) {
    const goodsArray = []
    const filedNames = this.fieldNames
    array.forEach(e => {
      goodsArray.push({
        goodsFullCode: getFieldValue(e, filedNames.goodsFullCode),
        goodsCode: e[filedNames.goodsCode],
        goodsAbbr: e[filedNames.goodsAbbr],
        goodsName: getFieldValue(e, filedNames.goodsName),
        goodsAlias: e[filedNames.goodsAlias],
        category: getFieldValue(e, filedNames.goodsCategory),
        unit: getFieldValue(e, filedNames.unit)
      })
    })
    return goodsArray
  }
  this.handleGoods = function () {
    this.goodsList.forEach(goods => {
      goods.category = goods.category.substring(0, goods.category.indexOf('_'))
    })
  }
  this.validateSupplier = function (value) {
    const array = toArray(value)
    const filedNames = this.fieldNames
    let fieldValue
    array.forEach(e => {
      if (!e[filedNames.supplierFullCode]) {
        throw new Error('数据格式错误：缺少字段【' + filedNames.supplierFullCode + '】')
      }
      fieldValue = getFieldValue(e, filedNames.supplierCode)
      if (!fieldValue) {
        throw new Error('数据格式错误：缺少字段【' + fieldValue + '】')
      }
      fieldValue = getFieldValue(e, filedNames.supplierName)
      if (!fieldValue) {
        throw new Error('数据格式错误：缺少字段【' + fieldValue + '】')
      }
    })
    return array
  }
  this.convertToSupplier = function (array) {
    const supplierArray = []
    const filedNames = this.fieldNames
    array.forEach(e => {
      supplierArray.push({
        supplierFullCode: e[filedNames.supplierFullCode],
        supplierCode: getFieldValue(e, filedNames.supplierCode),
        supplierName: getFieldValue(e, filedNames.supplierName),
        principal: e[filedNames.principal],
        tel: e[filedNames.tel],
        bank: e[filedNames.bank],
        account: e[filedNames.account]
      })
    })
    return supplierArray
  }
  this.handleSupplier = function () {
    this.supplierList.forEach(supplier => {
      supplier.category = supplier.supplierFullCode.substring(0, supplier.supplierFullCode.indexOf('.'))
    })
  }
  this.validatePurchaseOrder = function (value) {
    const array = toArray(value)
    const filedNames = this.fieldNames
    if (array.length > 0) {
      if (!array[0][filedNames.orderCode]) {
        throw new Error('数据格式错误：第一行缺少字段【' + filedNames.orderCode + '】')
      }
    }
    array.forEach(e => {
      if (!e[filedNames.goodsCode]) {
        throw new Error('数据格式错误：缺少字段【' + filedNames.goodsCode + '】')
      }
    })
    return array
  }
  this.convertToPurchaseOrder = function (array) {
    const orderArray = []
    const orderMap = new UglyMap()
    const filedNames = this.fieldNames
    let order
    let orderCode
    let lastOrderCode = ''
    array.forEach(e => {
      orderCode = e[filedNames.orderCode]
      if (!orderCode) {
        orderCode = lastOrderCode
      } else {
        lastOrderCode = orderCode
      }
      order = orderMap.computeIfAbsent(orderCode, (k) => {
        const o = {
          purchaseOrderCode: orderCode,
          createDate: moment(e[filedNames.createDate]).format('YYYY-MM-DD'),
          supplierName: getFieldValue(e, filedNames.supplierName),
          expectArriveDate: moment(e[filedNames.expectArriveDate]).format('YYYY-MM-DD'),
          purchaserName: e[filedNames.bizer],
          editorName: e[filedNames.editor],
          goodsList: []
        }
        orderArray.push(o)
        return o
      })
      order.goodsList.push({
        goodsFullCode: getFieldValue(e, filedNames.goodsFullCode),
        goodsCode: e[filedNames.goodsCode],
        goodsAbbr: e[filedNames.goodsAbbr],
        goodsName: getFieldValue(e, filedNames.goodsName),
        unit: getFieldValue(e, filedNames.unit),
        quantity: getFieldValue(e, filedNames.quantity),
        originalGoodsCode: e[filedNames.originalGoodsCode],
        originalGoodsName: getFieldValue(e, filedNames.goodsName),
        originalGoodsBatchCode: e[filedNames.originalGoodsBatchCode]
      })
    })
    console.log(orderArray, 'orderArray');
    return orderArray
  }
  this.validatePurchaseReceiveOrder = function (value) {
    const array = toArray(value)
    const filedNames = this.fieldNames
    array.forEach(e => {
      if (!e[filedNames.orderCode]) {
        throw new Error('数据格式错误：缺少字段【' + filedNames.orderCode + '】')
      }
      if (!e[filedNames.goodsCode]) {
        throw new Error('数据格式错误：缺少字段【' + filedNames.goodsCode + '】')
      }
      if (!e[filedNames.goodsBatchCode]) {
        throw new Error('数据格式错误：缺少字段【' + filedNames.goodsBatchCode + '】')
      }
    })
    return array
  }
  this.convertToPurchaseReceiveOrder = function (array) {
    const orderArray = []
    const orderMap = new UglyMap()
    const filedNames = this.fieldNames
    let order
    let orderCode
    array.forEach(e => {
      orderCode = e[filedNames.orderCode]
      order = orderMap.computeIfAbsent(orderCode, (k) => {
        const o = {
          sourceOrderCode: orderCode,
          sourceOrderDate: e[filedNames.createDate],
          warehouseName: getFieldValue(e, filedNames.warehouseName),
          supplierCode: getFieldValue(e, filedNames.supplierCode),
          supplierName: e[filedNames.supplierName],
          customerCode: e[filedNames.customerCode],
          customerName: e[filedNames.customerName],
          receiveAddress: e[filedNames.receiveAddress],
          province: e[filedNames.province],
          city: e[filedNames.city],
          memo: e[filedNames.memo],
          goodsList: []
        }
        orderArray.push(o)
        return o
      })
      order.goodsList.push({
        goodsFullCode: getFieldValue(e, filedNames.goodsFullCode),
        goodsCode: e[filedNames.goodsCode],
        goodsAbbr: e[filedNames.goodsAbbr],
        goodsName: e[filedNames.goodsName],
        unit: getFieldValue(e, filedNames.unit),
        goodsBatchFullCode: e[filedNames.goodsBatchCode],
        expirationDate: e[filedNames.expirationDate],
        quantity: getFieldValue(e, filedNames.quantity)
      })
    })

    return orderArray
  }
  this.handleOrderGoods = function (orderList) {
    orderList.forEach(order => {
      order.goodsList.forEach(goods => {
        const goodsBatchArray = splitGoodsBatchCode(goods.goodsBatchFullCode)
        goods.goodsBatchCode = goodsBatchArray[0]
        goods.concentration = goodsBatchArray[1]
        goods.concentrationUnit = goodsBatchArray[2]
        goods.specification = goodsBatchArray[3]
        goods.specificationUnit = goodsBatchArray[4]
      })
    })
  }
}
